package samsung.other;

import java.util.ArrayList;
import java.util.List;
import samsung.entities.Area;
import samsung.entities.AreaBuilder;
import samsung.exceptions.BrokenCountryBorderException;
import samsung.exceptions.NotConnectedCountriesException;
import samsung.exceptions.WrongCountriesNumberException;

/**
 * Class realized <code>Singleton</code> pattern, it describe methods for
 * simulation of program work.
 *
 * @author Vitaliy Muzalevskiy
 */
public class Controller {

    public static final int MIN_COUNTRY_NUMBER = 0;
    public static final int MAX_COUNTRY_NUMBER = 20;
    private List<Area> areas = new ArrayList<Area>();
    private static Controller instance = new Controller();
    private AreaBuilder builder = new AreaBuilder();
    private boolean finish;

    private Controller() {
    }

    public static Controller getInstance() {
        return instance;
    }

    private void addArea(int countriesNumber)
            throws NotConnectedCountriesException, BrokenCountryBorderException {
        Area area = builder.buildArea(countriesNumber);
        areas.add(area);
    }

    private void readInputValues() {
        Reader reader = new Reader();
        int countriesInArea = 0;
        try {
            countriesInArea = reader.readCountriesNumber();
        } catch (WrongCountriesNumberException e) {
            System.err.println("Countries number must be less than 20");
            readInputValues();
            return;
        } catch (NumberFormatException e){
            System.err.println("Integer number should be entered.");
            readInputValues();
            return;
        }
        if (countriesInArea != 0) {
            try {
                addArea(countriesInArea);
            } catch (NotConnectedCountriesException ex) {
                System.err.println("Countries in current area are not connected."
                        + "Enter area information once more.");
                readInputValues();
                return;
            } catch (BrokenCountryBorderException ex) {
                System.err.println("Countries in current area have crossing borders."
                        + "Enter area information once more.");
                readInputValues();
                return;
            }
            readInputValues();
        }
    }

    /**
     * Method that aggregate all methods needed to simulate current process. 
     */
    public void startSimulation() {
        readInputValues();
        while (!finish) {
            for (Area area : areas) {
                if (!area.isFinish()) {
                    area.makeDissemination();
                    area.finishDissemination();
                }
            }
            finish = finishSimulation();
        }
        printResults();
    }

    private void printResults() {
        Printer printer = new Printer();
        int areaCounter = 1;
        for (Area area : areas) {
            System.out.println(areaCounter++);
            printer.printResults(area.getResults());
        }
    }
    
    private boolean finishSimulation(){
        for (Area area : areas) {
            if(!area.isFinish()){
                return false;
            }
        }
        return true;
    }
}
